#  图片验证码序列化器
from redis import RedisError
from rest_framework import serializers
from django_redis import get_redis_connection

import logging
#日志记录器
logger = logging.getLogger('django')


class ImageCodeCheckSerializer(serializers.Serializer):
    """图片验证码序列化器,可以初步校验image-code-id和text"""
    image_code_id = serializers.UUIDField()
    text = serializers.CharField(max_length=4,min_length=4)

    # 对字段再次校验
    def validate(self, attrs):
        """
        对image-code-id和text联合校验
        :param attrs:
        :return:
        """
        # 读取validate-data里面的数据
        image_code_id = attrs.get('image_code_id')
        text = attrs.get('text')

        # 获取连接到redis数据库的对象
        redis_conn = get_redis_connection('verify_codes')

        # 获取redis中储存的图片验证码
        image_code_server = redis_conn.get('img_%s' % image_code_id)
        if image_code_server is None:
            raise serializers.ValidationError('无效验证码')
        # 删除图片验证码。防止暴力测试，必须先拿到在删除
        # 删除图片验证码是附带的可有可无的业务逻辑，不能阻塞主线的业务逻辑，所以出现了异常不需要响应数据，忽略衣长后逻辑继续执行
        try:
            redis_conn.delete('img_%s' % image_code_id)
        except RedisError as e:
            logger.error(e)

        # py3中在redis中获取到的数据都是bytes类型的
        # 需要先将bytes类型的数据解码，转成字符串
        image_code_server = image_code_server.decode()
        # 对比text和服务器储存的图片验证码
        if text.lower() != image_code_server.lower():
            raise serializers.ValidationError('五篇验证码输入有误')


        # 判断用户是否在60秒内使用同一个手机号码获取短信
        mobile = self.context['view'].kwargs['mobile']
        send_flag = redis_conn.get('send_flag_%s' % mobile)
        if send_flag:
            raise serializers.ValidationError('频繁发送短信')
        return attrs